﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PersistentManager.Descriptors;

namespace PersistentManager.Metadata.ExtractionRules
{
    internal class TablePerTypeExtraction : AbstractExtraction
    {
        protected override EntityMetadata BeginExtraction( EntityMetadata metadata , Mapping.XmlEntityMapping mapping )
        {
            if ( mapping.HasInheritance && !mapping.IsDiscriminating )
            {
                PropertyMetadata relationPropety = new PropertyMetadata();
                string relationColumn = mapping.RelationColumn;
                string joinColumn = mapping.JoinColumn;

                if (!joinColumn.IsNullOrEmpty())
                {
                    PropertyMetadata key = MetaDataManager.MetaInfo( mapping.BaseType ).GetKeyByMapping(joinColumn);
                    relationPropety.ClassDefinationName = key.ClassDefinationName;
                    relationPropety.PropertyType = key.PropertyType;
                    relationPropety.MappingName = key.MappingName;
                }
                else
                {
                    relationPropety.ClassDefinationName = MetaDataManager.MetaInfo( mapping.BaseType ).Keys[0].ClassDefinationName;
                    relationPropety.PropertyType = MetaDataManager.MetaInfo( mapping.BaseType ).Keys[0].PropertyType;
                    joinColumn = MetaDataManager.MetaInfo( mapping.BaseType ).Keys[0].MappingName;
                    relationPropety.MappingName = joinColumn;
                }

                if (relationColumn.IsNullOrEmpty())
                {
                    relationColumn = relationPropety.MappingName;
                }

                relationPropety.IsInheritance = true;
                relationPropety.IsUniqueIdentifier = true;

                relationPropety.AddJoin(new JoinMetadata
                                                {
                                                    RelationColumn = relationColumn,
                                                    JoinColumn = joinColumn
                                                }
                                       );

                relationPropety.RelationType = mapping.BaseType;
                relationPropety.IsAutoGenerated = false;
                relationPropety.MappingName = (relationColumn.IsNullOrEmpty()) ? relationPropety.MappingName : relationColumn;
                relationPropety.DeclaringType = (relationColumn.IsNullOrEmpty()) ? mapping.BaseType : mapping.Type;

                metadata.InheritanceRelation = relationPropety;

                if ( metadata.InheritanceRelation.IsNotNull() )
                {
                    metadata.ColumnInfoBag.Add( metadata.InheritanceRelation );
                }
            }

            return metadata;
        }

        protected override void EndExtraction()
        {
            return;
        }

        protected override void ValidateMapping()
        {
            return;
        }
    }
}
